package com.android.lovely.framework

import android.widget.Toast
import androidx.annotation.StringRes
import com.android.lovely.api.LovelyException
import com.kotlin.extensions.appContext
import com.kotlin.extensions.coroutine.CoroutineExt.launchSafety
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.isActive
import kotlinx.coroutines.withContext
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.cancellation.CancellationException

/**
 *
 * @author why
 * @date 2025/3/7 14:48
 */
sealed class UIState {
    var isResumed = false
    abstract fun consume()
}


data class ToastUiState(val msg: String) : UIState() {
    override fun consume() {
        isResumed = true
    }
}

data class LoadingUiState(val show: Boolean, var canCancel: Boolean = false) : UIState() {
    override fun consume() {
        isResumed = true
    }
}

// 使用伴生对象封装Flow相关逻辑
object UIController {
    private val _showToastUiState = MutableSharedFlow<ToastUiState>(
        replay = 1,
        extraBufferCapacity = 10,
        onBufferOverflow = BufferOverflow.DROP_OLDEST
    )
    val showToastUiState: SharedFlow<ToastUiState> = _showToastUiState

    private val _showLoadingUiState = MutableSharedFlow<LoadingUiState>(
        replay = 1,
        extraBufferCapacity = 10,
        onBufferOverflow = BufferOverflow.DROP_OLDEST
    )
    val showLoadingUiState: SharedFlow<LoadingUiState> = _showLoadingUiState

    fun showToast(msg: String) {
        if (msg.isNotEmpty()) {
            _showToastUiState.tryEmit(ToastUiState(msg))
        }
    }

    fun showToast(@StringRes msgId: Int) {
        runCatching {
            val msg = appContext.getString(msgId)
            showToast(msg)
        }.onFailure { it.printStackTrace() }
    }

    fun showLoading(canCancel: Boolean = true) {
        _showLoadingUiState.tryEmit(LoadingUiState(true, canCancel))
    }

    fun dismissLoading() {
        _showLoadingUiState.tryEmit(LoadingUiState(false))
    }
}

// 扩展函数用于简化协程加载逻辑
fun CoroutineScope.launchWithLoading(
    context: CoroutineContext = this.coroutineContext,
    block: suspend CoroutineScope.() -> Unit
) = launchSafety(context) {
    UIController.showLoading()
    try {
        block()
    } finally {
        UIController.dismissLoading()
    }
}

// 改进连续操作逻辑
suspend fun <T> doContinuousOperation(
    retryCount: Int = Int.MAX_VALUE,
    block: suspend CoroutineScope.() -> T
): T? = withContext(Dispatchers.IO) {
    var remainingAttempts = retryCount
    while (isActive && remainingAttempts >= 0) {
        runCatching {
            return@withContext block()
        }.onFailure { throwable ->
            if (throwable is LovelyException) {
                return@withContext null
            }
            if (throwable is CancellationException) return@withContext null
            remainingAttempts--
            delay(1300)
            throwable.printStackTrace()
        }
    }
    return@withContext null
}